// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Windows.Graphics.Imaging;
using Windows.Media;

namespace CommunityToolkit.WinUI.Helpers;

/// <summary>
/// Provides data for the <see cref="CameraHelper.FrameArrived"/> event.
/// </summary>
#pragma warning disable CA1001 // Types that own disposable fields should be disposable
public class FrameEventArgs : EventArgs
#pragma warning restore CA1001 // Types that own disposable fields should be disposable
{
    private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
    private VideoFrame? _videoFrame;
    private VideoFrame? _videoFrameCopy;

    /// <summary>
    /// Gets the video frame.
    /// </summary>
    public VideoFrame VideoFrame
    {
        get
        {
            _semaphore.Wait();

            // The VideoFrame could be disposed at any time so we need to create a copy we can use.
            if (_videoFrameCopy == null &&
                _videoFrame != null &&
                _videoFrame.SoftwareBitmap != null)
            {
                try
                {
                    _videoFrameCopy = VideoFrame.CreateWithSoftwareBitmap(SoftwareBitmap.Copy(_videoFrame.SoftwareBitmap));
                }
                catch (Exception)
                {
                }
            }

            _semaphore.Release();
            _videoFrame?.SoftwareBitmap?.Dispose();
            _videoFrame?.Dispose();
            return _videoFrameCopy! ?? _videoFrame!;
        }

        internal set
        {
            _videoFrame = value;
        }
    }
}
